package tools;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Classe permettant de lire les champs et valeurs dans un fichier de configuration formaté de la manière suivante :
 * # commentaire
 * CHAMP_1=valeur_1
 * CHAMP_2=valeur_2
 * @author Jean-François Augé
 */
public class ConfParser {
	
	private Map<String, String> champs = new HashMap<String, String>();
	private Map<Integer, String> lines = new HashMap<Integer, String>();
	private Map<Integer, String> comments = new HashMap<Integer, String>();
	
	/**
	 * Charge en mémoire le fichier rentré en paramètre.
	 * @param f
	 * @throws IOException
	 */
	public void parse(File f) throws IOException {
		FileReader in;
		try {
			in = new FileReader(f);
			BufferedReader buf = new BufferedReader(in);
			int lineNumber = 1;
			String line;
			String[] values;
			Pattern comm = Pattern.compile("^#");
			Matcher matcher;

			while ( (line = buf.readLine()) != null) {
				matcher = comm.matcher(line);
				if(!matcher.find()) {
					values = line.split("=");
					champs.put(values[0], values[1]);
					lines.put(lineNumber, values[0]);
				}
				else{
					comments.put(lineNumber, line);
				}
				lineNumber++;
			}
			
			buf.close();
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Sauvegarde en mémoire le fichier rentré en paramètre.
	 * @param f
	 * @throws IOException
	 */
	public void saveInFile(File f, Map<String, String> newFields) throws IOException {
		/*for(Entry e : newFields.entrySet())
			System.out.println(e.getKey()+" "+e.getValue());*/
		
		int lineNumber = 1;
		boolean goOn = true;
		String line, tempField;
		FileWriter out = new FileWriter(f);
		BufferedWriter buf = new BufferedWriter(out);
		
		while(goOn){
			line = "";
			if(comments.get(lineNumber) != null){
				if(lineNumber > 1)	buf.write("\n");
				tempField = comments.get(lineNumber);
				line = tempField;
				buf.write(line);
			}
			else if(lines.get(lineNumber) != null){
				if(lineNumber > 1)	buf.write("\n");
				tempField = lines.get(lineNumber);
				line = champs.get(tempField);
				buf.write(tempField+"="+line);
			}
			else	goOn = false;
			lineNumber++;
		}
		
		buf.close();
		out.close();
	}
	
	public void modifyField(String field, String value){
		if(champs.containsKey(field)){
			champs.remove(field);
			champs.put(field, value);
		}
	}
	
	public void addField(String field, String value){
		if(!champs.containsKey(field)){
			champs.put(field, value);
			lines.put(lines.size()+comments.size()+1, field);
		}
		else	modifyField(field, value);
	}
	
	/**
	 * Retourne la valeur pour le champ demandé.
	 * @param champ
	 * @return
	 */
	public String getValue(String champ) {
		return champs.get(champ);
	}
	
	public Map<String, String> getChamps() { return champs; }
	public void setChamps(Map<String, String> champs) { this.champs = champs; }

	
	// tests
	public static void main(String[] args) {
		ConfParser parser = new ConfParser();
		try {
			parser.parse(new File(AppletConstant.SSL_CONF_FILE));
		} catch (IOException e) {
			e.printStackTrace();
		}
		for(Entry<String, String> entry : parser.getChamps().entrySet())
		    System.out.println(entry.getKey() + "=" + entry.getValue());
		//System.out.println(parser.getValue("winPath3"));
		
		System.out.println("Test modification configuration file:");
		
		parser.modifyField("PATH_KEYSTORE", System.getProperty("user.home")+System.getProperty("file.separator")+"kraken"+System.getProperty("file.separator")+"mySrvKeystore");
		
		try {
			parser.saveInFile(new File(System.getProperty("user.home")+System.getProperty("file.separator")+"kraken"+System.getProperty("file.separator")+"sslserver_modify.conf"),parser.getChamps());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		for(Entry<String, String> entry : parser.getChamps().entrySet())
		    System.out.println(entry.getKey() + "=" + entry.getValue());
		
		System.out.println("\nTest ajout configuration file:");
		
		parser.addField("toto","tata");
		
		try {
			parser.saveInFile(new File(System.getProperty("user.home")+System.getProperty("file.separator")+"kraken"+System.getProperty("file.separator")+"sslserver_modify.conf"),parser.getChamps());
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		for(Entry<String, String> entry : parser.getChamps().entrySet())
		    System.out.println(entry.getKey() + "=" + entry.getValue());
	}

}
